From 298384fd250429bbc7a7836cd04ef8a3be548b7f Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Thu, 27 Jan 2005 23:49:46 +0000 Subject: [PATCH] bitkeeper revision 1.1159.231.11 (41f97e1amKuDHSrW5ZWKsTy4ZIfNRA) Fix the direction flag for string I/O instructions. Signed-off-by: Jun Nakajima Signed-off-by: Chengyuan Li Signed-off-by: ian.pratt@cl.cam.ac.uk --- xen/arch/x86/vmx.c | 4 ++++ xen/arch/x86/vmx_io.c | 26 ++++++++++++++------------ xen/include/public/io/ioreq.h | 3 ++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 194311242b..acfc14eb4c 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -352,6 +352,10 @@ static void vmx_io_instruction(struct xen_regs *regs, p->size = (exit_qualification & 7) + 1; if (test_bit(4, &exit_qualification)) { + unsigned long eflags; + + __vmread(GUEST_EFLAGS, &eflags); + p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0; p->pdata_valid = 1; p->u.pdata = (void *) ((p->dir == IOREQ_WRITE) ? regs->esi diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 02333531a1..85862f94ea 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -39,8 +39,7 @@ void vmx_io_assist(struct exec_domain *ed) struct domain *d = ed->domain; execution_context_t *ec = get_execution_context(); unsigned long old_eax; - unsigned long eflags; - int dir; + int sign; /* clear the pending event */ ed->vcpu_info->evtchn_upcall_pending = 0; @@ -68,24 +67,27 @@ void vmx_io_assist(struct exec_domain *ed) return; } - __vmread(GUEST_EFLAGS, &eflags); - dir = (eflags & X86_EFLAGS_DF); + sign = (p->df) ? -1 : 1; + if (p->port_mm) { + if (p->pdata_valid) { + ec->esi += sign * p->count * p->size; + ec->edi += sign * p->count * p->size; + } else { + if (p->dir == IOREQ_WRITE) { + return; + } + } + } if (p->dir == IOREQ_WRITE) { if (p->pdata_valid) { - if (!dir) - ec->esi += p->count * p->size; - else - ec->esi -= p->count * p->size; + ec->esi += sign * p->count * p->size; ec->ecx -= p->count; } return; } else { if (p->pdata_valid) { - if (!dir) - ec->edi += p->count * p->size; - else - ec->edi -= p->count * p->size; + ec->edi += sign * p->count * p->size; ec->ecx -= p->count; return; } diff --git a/xen/include/public/io/ioreq.h b/xen/include/public/io/ioreq.h index c10dc46995..ac47cd9ec5 100644 --- a/xen/include/public/io/ioreq.h +++ b/xen/include/public/io/ioreq.h @@ -41,10 +41,11 @@ typedef struct { u64 data; /* data */ void *pdata; /* pointer to data */ } u; - u8 state:5; + u8 state:4; u8 pdata_valid:1; /* if 1, use pdata above */ u8 dir:1; /* 1=read, 0=write */ u8 port_mm:1; /* 0=portio, 1=mmio */ + u8 df:1; } ioreq_t; #define MAX_VECTOR 256 -- 2.30.2